LOADER_BASE_ADDR equ 0x7e00;
LOADER_SECTORS equ 20;
LOADER_START_SECTOR equ 2;

bits 16


section .mbr vstart=0x7c00

mov ax,3;
int  0x10;

    ; Read OS loader via BIOS interrupt.
    ; Set the function number, 2 means read sector.
    mov ah, 2
    ; Set the number of sectors to read.
    mov al, LOADER_SECTORS
    ; Set the cylinder.
    mov ch, 0
    ; Set the head.
    mov dh, 0
    ; Set sector.
    mov cl, LOADER_START_SECTOR
    ; Set the drive letter, 0 ~ 0x7F is floppy disk, 0x80 ~ 0xFF is hard disk.
    mov dl, 0x80
    ; Set the destination address.
    mov bx, LOADER_BASE_ADDR
    int 0x13
    ; If the disk read error, the BIOS will set the CF of the flags register to 1, and AH is the error code.
    ;jc disk_error

;disk_error:
;    mov [REGISTER_AX], ax
;    mov ax, DISK_READ_ERROR
;    call print
;    mov ax, [REGISTER_AX]
;    call print_hex
;    jmp $

cli;

in al,0x92
or al,0b0000_0010;
out 0x92, al;

lgdt [gdtpointer]

xor eax,eax;
mov eax,cr0;
or eax,0x1;
mov cr0,eax;

jmp 0x8:protect


bits 32
protect:

xor ax,ax;
mov ax,0x10;
mov ds,ax;
mov ss,ax;
mov es,ax;
mov eax,0x7c00;
mov esp,eax;
mov ebp,eax;

jmp LOADER_BASE_ADDR;;

gdtstart:
    dd 0x0;
    dd 0x0;
gdtcode:
    dw 0b1111_1111_1111_1111;
    dw 0b0000_0000_0000_0000;
    db 0b0000_0000;
    db 0b1001_1110;
    db 0b1100_1111;
    db 0b0000_0000;
gdtdata:
    dw 0b1111_1111_1111_1111;
    dw 0b0000_0000_0000_0000;
    db 0b0000_0000;
    db 0b1001_0010;
    db 0b1100_1111;
    db 0b0000_0000;

gdtend:

gdtpointer:
    dw gdtend-gdtstart;
    dd gdtstart;

times 510-($-$$) db 0;
db 0x55;
db 0xaa;
